package org.apache.ocean.main.search;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ocean.main.Index.IndexSnapshot;
import org.apache.ocean.main.search.Search.Aggregate;
import org.apache.ocean.main.search.cache.FieldCacheKey.FieldIndex;

public class IndexGroupBySearch implements HitCollector {
	private List<Aggregate> aggregates;
	private List<FieldIndex> fieldIndices;
	private IndexSnapshot indexSnapshot;
	private Map<Orders, Row> rows = new HashMap<Orders, Row>();

	public IndexGroupBySearch(List<Aggregate> aggregates, IndexSnapshot indexSnapshot) {
		this.aggregates = aggregates;
		this.indexSnapshot = indexSnapshot;
		fieldIndices = new ArrayList<FieldIndex>();
		for (Aggregate aggregate : aggregates) {
			fieldIndices.add(indexSnapshot.getFieldIndex(aggregate.getField()));
		}

	}
  
	public static class Summer {
		public Number total;
	}
	
	public static class Row {
		private int[] orders;
		private Number[] values;
		private List<Aggregate> aggregates;

		public Row(int[] orders, Number[] values) {
			this.orders = orders;
			this.values = values;
		}

		public void merge(Number[] newValues) {
      for (int x=0; x < aggregates.size(); x++) {
      	Aggregate aggregate = aggregates.get(x);
      	
      }
		}
	}

	public static class Orders {
		private int[] orders;
		private int hashCode;

		public Orders(int[] orders) {
			this.orders = orders;
			hashCode = Arrays.hashCode(orders);
		}

		public boolean equals(Object obj) {
			if (obj == null)
				return false;
			final Orders other = (Orders) obj;
			if (hashCode != other.hashCode)
				return false;
			if (!Arrays.equals(orders, other.orders))
				return false;
			return true;
		}

		public int hashCode() {
			return hashCode;
		}
	}

	public void addRow(int[] ordersArray, Number[] values) {
		Orders orders = new Orders(ordersArray);
		Row row = rows.get(orders);
		if (row == null) {
			row = new Row(ordersArray, values);
			rows.put(orders, row);
		} else {
			row.merge(values);
		}
	}

	public void collect(int doc, float score) {
		int[] orders = new int[fieldIndices.size()];
		Number[] values = new Number[fieldIndices.size()];
		int x = 0;
		for (FieldIndex fieldIndex : fieldIndices) {
			orders[x] = fieldIndex.order[doc];
			values[x] = (Number) fieldIndex.valueIndices[orders[x]].value;
			x++;
		}
		addRow(orders, values);
	}
}
